using B.S.XZYData.Api.Wrter.Application.Command.AssemblyWorkOrder;
using B.S.XZYData.Domain.ZSHH;
using B.S.XZYData.Domain.BaseEntities;
using B.S.XZYData.ErrorCode;
using B.S.XZYData.Infrastructure.Interface;
using MediatR;
using Microsoft.Extensions.Logging;
using System.Transactions;
using System.Linq;
using Yitter.IdGenerator;

namespace B.S.XZYData.Api.Wrter.Application.Handler.AssemblyWorkOrder
{
    /// <summary>
    /// 修改装配工单处理器
    /// </summary>
    public class UpdateAssemblyWorkOrderHandler : IRequestHandler<UpdateAssemblyWorkOrderCommand, ApiResult<bool>>
    {
        private readonly IBaseRepository<Domain.ZSHH.AssemblyWorkOrder> _assemblyWorkOrderRepo;
        private readonly IBaseRepository<AssemblyWorkOrderProductDetail> _productDetailRepo;
        private readonly ILogger<UpdateAssemblyWorkOrderHandler> _logger;

        public UpdateAssemblyWorkOrderHandler(
            IBaseRepository<Domain.ZSHH.AssemblyWorkOrder> assemblyWorkOrderRepo,
            IBaseRepository<AssemblyWorkOrderProductDetail> productDetailRepo,
            ILogger<UpdateAssemblyWorkOrderHandler> logger)
        {
            _assemblyWorkOrderRepo = assemblyWorkOrderRepo;
            _productDetailRepo = productDetailRepo;
            _logger = logger;
        }

        public async Task<ApiResult<bool>> Handle(UpdateAssemblyWorkOrderCommand request, CancellationToken cancellationToken)
        {
            var res = new ApiResult<bool>();
            try
            {
                // 验证装配工单是否存在
                var existingWorkOrder = await _assemblyWorkOrderRepo.GetValue(request.Id);
                if (existingWorkOrder == null)
                {
                    res.Msg = "装配工单不存在";
                    res.Code = ApiEnum.Fail;
                    return await System.Threading.Tasks.Task.FromResult(res);
                }

                // 验证产品明细不能为空
                if (request.ProductDetails == null || !request.ProductDetails.Any())
                {
                    res.Msg = "产品明细不能为空";
                    res.Code = ApiEnum.Fail;
                    return await System.Threading.Tasks.Task.FromResult(res);
                }

                // 验证产品明细数据
                foreach (var detail in request.ProductDetails)
                {
                    if (string.IsNullOrWhiteSpace(detail.HierarchyNumber))
                    {
                        res.Msg = "层级编号不能为空";
                        res.Code = ApiEnum.Fail;
                        return await System.Threading.Tasks.Task.FromResult(res);
                    }
                    if (string.IsNullOrWhiteSpace(detail.ProductNumber))
                    {
                        res.Msg = "产品编号不能为空";
                        res.Code = ApiEnum.Fail;
                        return await System.Threading.Tasks.Task.FromResult(res);
                    }
                    if (string.IsNullOrWhiteSpace(detail.ProductName))
                    {
                        res.Msg = "产品名称不能为空";
                        res.Code = ApiEnum.Fail;
                        return await System.Threading.Tasks.Task.FromResult(res);
                    }
                    if (detail.Quantity <= 0)
                    {
                        res.Msg = "数量必须大于0";
                        res.Code = ApiEnum.Fail;
                        return await System.Threading.Tasks.Task.FromResult(res);
                    }
                }

                using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    // 1. 更新装配工单基本信息
                    existingWorkOrder.DocumentNumber = request.DocumentNumber;
                    existingWorkOrder.Remarks = request.Remarks;
                    existingWorkOrder.Updator = request.Updator;
                    existingWorkOrder.UpdatorDate = DateTime.Now;

                    var workOrderResult = await _assemblyWorkOrderRepo.UpdateAsync(existingWorkOrder);
                    if (workOrderResult <= 0)
                    {
                        res.Msg = "更新装配工单失败";
                        res.Code = ApiEnum.Fail;
                        return await System.Threading.Tasks.Task.FromResult(res);
                    }

                    // 2. 删除原有的产品明细（逻辑删除）
                    var existingProductDetails = _productDetailRepo.GetAll()
                        .Where(x => !x.IsDeleted && x.WorkOrderId == request.Id)
                        .ToList();

                    if (existingProductDetails.Any())
                    {
                        foreach (var detail in existingProductDetails)
                        {
                            detail.IsDeleted = true;
                            detail.Updator = request.Updator;
                            detail.UpdatorDate = DateTime.Now;
                            await _productDetailRepo.UpdateAsync(detail);
                        }
                    }

                    // 3. 创建新的产品明细
                    var newProductDetails = new List<AssemblyWorkOrderProductDetail>();
                    foreach (var detailDto in request.ProductDetails)
                    {
                        var productDetail = new AssemblyWorkOrderProductDetail
                        {
                            Id = YitIdHelper.NextId(),
                            WorkOrderId = request.Id,
                            HierarchyNumber = detailDto.HierarchyNumber,
                            ProductNumber = detailDto.ProductNumber,
                            ProductName = detailDto.ProductName,
                            ProductSpecification = detailDto.ProductSpecification,
                            WorkOrderDetailNumber = detailDto.WorkOrderDetailNumber,
                            Quantity = detailDto.Quantity,
                            CompletedQuantity = detailDto.CompletedQuantity ?? 0,
                            Creator = request.Updator, // 修改时，创建人设为修改人
                            CreatorDate = DateTime.Now
                        };
                        newProductDetails.Add(productDetail);
                    }

                    // 批量插入新的产品明细
                    foreach (var detail in newProductDetails)
                    {
                        var detailResult = await _productDetailRepo.CreateAsync(detail);
                        if (detailResult <= 0)
                        {
                            res.Msg = "创建产品明细失败";
                            res.Code = ApiEnum.Fail;
                            return await System.Threading.Tasks.Task.FromResult(res);
                        }
                    }

                    // 4. 计算并更新工单统计信息
                    await UpdateWorkOrderStatisticsAsync(request.Id);

                    scope.Complete();
                    res.Data = true;
                    res.Code = ApiEnum.Success;
                    res.Msg = "修改装配工单成功";
                }

                return await System.Threading.Tasks.Task.FromResult(res);
            }
            catch (Exception ex)
            {
                _logger.LogError($"修改装配工单异常：{ex.Message}");
                res.Msg = "修改装配工单异常：" + ex.Message;
                res.Code = ApiEnum.Error;
                return await System.Threading.Tasks.Task.FromResult(res);
            }
        }

        /// <summary>
        /// 更新工单统计信息（工单数、已结束工单数、单据进度）
        /// </summary>
        /// <param name="workOrderId">装配工单ID</param>
        private async System.Threading.Tasks.Task UpdateWorkOrderStatisticsAsync(long workOrderId)
        {
            try
            {
                // 查询该工单下的所有产品明细
                var productDetails = _productDetailRepo.GetAll()
                    .Where(x => !x.IsDeleted && x.WorkOrderId == workOrderId)
                    .ToList();

                if (!productDetails.Any())
                    return;

                // 1. 计算工单数（产品明细数据条数）
                var workOrderCount = productDetails.Count;

                // 2. 计算已结束工单数量（完成数之和）
                var completedWorkOrderCount = productDetails.Sum(x => x.CompletedQuantity ?? 0);

                // 3. 计算单据进度（已结束工单/工单数*100%）
                decimal documentProgress = 0;
                if (workOrderCount > 0)
                {
                    documentProgress = Math.Round((decimal)completedWorkOrderCount / workOrderCount * 100, 2);
                }

                // 4. 更新装配工单的统计信息
                var workOrder = await _assemblyWorkOrderRepo.GetValue(workOrderId);
                if (workOrder != null)
                {
                    workOrder.WorkOrderCount = workOrderCount;
                    workOrder.CompletedWorkOrderCount = completedWorkOrderCount;
                    workOrder.DocumentProgress = documentProgress;
                    workOrder.UpdatorDate = DateTime.Now;

                    await _assemblyWorkOrderRepo.UpdateAsync(workOrder);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError($"更新工单统计信息异常：{ex.Message}");
            }
        }
    }
} 